package com.kaikeba.mvc;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 映射器（包含了大量的网址与方法的对应关系）
 */
public class HandlerMapping {

    private static Map<String,MVCMapping> data = new HashMap<>();

    public static MVCMapping get(String url){
        MVCMapping mapping = data.get(url);
        return mapping;
    }

    /**
     * 将properties文件中配置的全部类中用于处理请求的方法放入集合中
     * @param is
     */
    public static void load(InputStream is){

        Properties ppt = new Properties();
        try {
            ppt.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取配置文件中全部的servlet类
        Collection<Object> values = ppt.values();
        if (values!=null){
            for (Object cla : values) {
                String className = (String)cla;
                //反射加载类
                try {
                    Class c = Class.forName(className);
                    Object obj = c.getConstructor().newInstance();
                    //处理类中各个方法
                    Method[] methods = c.getMethods();
                    if (methods!=null){
                        for (Method method : methods) {
                            //方法各个注解
                            Annotation[] annotations = method.getAnnotations();
                            for (Annotation annotation : annotations) {
                                if (annotation instanceof ResponseBody){
                                    MVCMapping mapping = new MVCMapping(obj,method,ResponseType.TEXT);
                                    Object o = data.put(((ResponseBody)annotation).value(),mapping);
                                    if (o!=null){
                                        throw new RuntimeException("请求地址重复"+((ResponseBody)annotation).value());
                                    }
                                }else if (annotation instanceof ResponseView){
                                    MVCMapping mapping = new MVCMapping(obj,method,ResponseType.VIEW);
                                    Object o = data.put(((ResponseView)annotation).value(),mapping);
                                    if (o!=null){
                                        throw new RuntimeException("请求地址重复"+((ResponseView)annotation).value());
                                    }
                                }
                            }
                        }
                    }


                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 内部类：
     *  映射对象，每一个对象封装了一个方法，用于处理请求
     */
    public static class MVCMapping{
        private Object object;
        private Method method;
        private ResponseType type;

        @Override
        public String toString() {
            return "MVCMapping{" +
                    "object=" + object +
                    ", method=" + method +
                    ", type=" + type +
                    '}';
        }

        public MVCMapping(Object object, Method method, ResponseType type) {
            this.object = object;
            this.method = method;
            this.type = type;
        }

        public MVCMapping() {
        }

        public Object getObject() {
            return object;
        }

        public void setObject(Object object) {
            this.object = object;
        }

        public Method getMethod() {
            return method;
        }

        public void setMethod(Method method) {
            this.method = method;
        }

        public ResponseType getType() {
            return type;
        }

        public void setType(ResponseType type) {
            this.type = type;
        }
    }
}
